package com.appspot.bibtable.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

import javax.jdo.Extent;
import javax.jdo.PersistenceManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.appspot.bibtable.PMF;
import com.appspot.bibtable.model.ReferenceEntity;
import com.appspot.bibtable.model.UserInfo;
import com.appspot.bibtable.util.HtmlUtility;
import com.appspot.bibtable.util.StringUtility;
import com.appspot.bibtable.view.html.HtmlTemplate;
import com.appspot.bibtable.view.html.ReferenceListTable;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public class SearchItemServlet extends HttpServlet
{
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		response.setCharacterEncoding("UTF-8");
		PrintWriter writer = response.getWriter();

		HtmlTemplate template = new HtmlTemplate();
		template.setTitle("Search Result");
		template.setRequest(request);

		template.startDocument(writer);
		template.startContent(writer);

		UserService service = UserServiceFactory.getUserService();
		PersistenceManager manager = PMF.get().getPersistenceManager();

		Extent<ReferenceEntity> extent = null;
		try
		{
			String filter = request.getParameter("query");
			String sort = request.getParameter("sort");
			String start = request.getParameter("start");
			long startIndex = start == null ? 0 : Long.parseLong(start);
			boolean debug = request.getParameter("debug") != null;

			UserInfo userInfo = UserInfo.getUserInfoOf(service.getCurrentUser(), manager);

			List<ReferenceEntity> list = null;

			extent = manager.getExtent(ReferenceEntity.class, false);

			int displayCount = userInfo == null ? 50 : userInfo.getDisplayCount();
			if (displayCount <= 0)
			{
				userInfo.setDisplayCount(50);
				displayCount = 50;
			}
			else if (displayCount > 1000)
			{
				userInfo.setDisplayCount(1000);
				displayCount = 1000;
			}

			QueryBuilder<ReferenceEntity> builder = new QueryBuilder<ReferenceEntity>(manager, extent);
			builder.setFilter(filter);
			builder.setSort(sort);
			builder.setRange(start, displayCount);

			list = builder.executeQuery();

			template.printSearchBox(writer);

			ReferenceListTable table = new ReferenceListTable();
			table.setUserInfo(userInfo);
			table.setId("bibtable");
			table.addClass("stripe");
			table.setPersistenceManager(manager);
			if (debug)
			{
				StringBuilder caption = new StringBuilder();
				caption.append("<code>");
				caption.append(HtmlUtility.encode(builder.getQueryString()));
				Map<String, Object> parameters = builder.getParameters();
				if (parameters.size() > 0)
				{
					for (String name : parameters.keySet())
					{
						caption.append("<br />");
						caption.append(name + " = " + parameters.get(name));
					}
				}
				caption.append("</code>");
				table.setCaption(caption.toString());
			}

			writer.write("<form action=\"/download\" method=\"post\">");
			table.startTable(writer);
			for (ReferenceEntity entity : list)
			{
				table.addReference(entity, writer);
			}
			table.endTable(writer);

			writer.write("<div id=\"download\">");
			writer.write("<select name=\"format\">");
			writer.write("<option value=\"plain\" selected=\"selected\">plain text</option>");
			writer.write("</select>");
			writer.write("<input type=\"submit\" value=\"Download\" />");
			writer.write("</div>");
			writer.write("</form>");

			String path = request.getQueryString();
			if (StringUtility.isNullOrEmpty(path))
			{
				path = "/search?";
			}
			else
			{
				path = QueryBuilder.removeParameterFromPathAndQuery("/search?" + path, "start").replaceAll("&{2,}", "&").replaceAll("&", "&amp;");
				path =  path + "&amp;";
			}
			writer.write("<div id=\"page-navigation\">");
			if (startIndex > 0)
			{
				writer.write("<a href=\"" + path + "start=" + Math.max(startIndex - displayCount, 0) + "\">");
				writer.write("Previous");
				writer.write("</a>");
				writer.write(" <span class=\"splitter\">|</span> ");
			}
			writer.write("<a href=\"" + path + "start=" + (startIndex + displayCount) + "\">");
			writer.write("Next");
			writer.write("</a>");
			writer.write("</div>");
		}
		finally
		{
			if (extent != null)
			{
				extent.closeAll();
			}
			manager.close();
		}

		template.endContent(writer);
		template.endDocument(writer);
	}
}
